﻿namespace DemoApp_MRU
{
    using DemoApp_MRU.ViewModels.Base;
    using MRULib.MRU.ViewModels;
    using MRULib.MRU.ViewModels.Base;
    using MRUModelLib.Models.Persistables;
    using System;
    using System.IO;
    using System.Windows;
    using System.Windows.Input;
    using System.Xml;
    using System.Xml.Serialization;

    /// <summary>
    /// Class manages the viewmodel objects for the application.
    /// </summary>
    public class AppViewModel : BaseViewModel
    {
        #region fields
        private MRUListViewModel mMruList = null;
        private ICommand mGetXMLCommand;
        private ICommand mSetXMLCommand;
        private string mXMLDemoText;
        #endregion fields

        #region constructors
        /// <summary>
        /// Class construtor
        /// </summary>
        public AppViewModel()
        {
            mMruList = new MRUListViewModel()
            {
                // Invoke this callback method when a file link is clicked
                LoadFileCommandDelegate = LoadFile
            };
        }
        #endregion constructors

        #region properties
        /// <summary>
        /// Gets an MRU List property to manage a list of recently used files.
        /// </summary>
        public MRUListViewModel MruList
        {
            get
            {
                return mMruList;
            }
        }

        /// <summary>
        /// Gets a command that reset the XML text with the XML
        /// representation of the current demo data.
        /// </summary>
        public ICommand GetXMLCommand
        {
            get
            {
                if (mGetXMLCommand == null)
                {
                    mGetXMLCommand = new RelayCommand<object>((p) =>
                    {
                        var persist = MruList.GetPersistable();

                        XMLDemoText = PersistObject(persist);
                    });
                }

                return mGetXMLCommand;
            }
        }

        /// <summary>
        /// Gets a command that reset the XML text with the XML
        /// representation of the current demo data.
        /// </summary>
        public ICommand SetXMLCommand
        {
            get
            {
                if (mSetXMLCommand == null)
                {
                    mSetXMLCommand = new RelayCommand<object>((p) =>
                    {
                        MRUListPersistable persist = XmlDeserializeFromString<MRUListPersistable>(XMLDemoText);
                        MruList.SetPersistable(persist);
                    });
                }

                return mSetXMLCommand;
            }
        }

        /// <summary>
        /// Gets/sets the XML Demo text that simulates load save of MRU items.
        /// </summary>
        public string  XMLDemoText
        {
            get
            {
                return mXMLDemoText;
            }

            set
            {
                if (mXMLDemoText != value)
                {
                    mXMLDemoText = value;
                    RaisePropertyChanged(() => XMLDemoText);
                }
            }
        }
        #endregion properties

        #region methods
        /// <summary>
        /// Is invoked when a file click or Load File is invoked from the MRU control.
        /// </summary>
        /// <param name="filePathName"></param>
        public void LoadFile(string filePathName)
        {
            MessageBox.Show("Demo Opening File: " + filePathName);
        }

        #region Xml String serialization
        private string PersistObject(MRUModelLib.Models.Persistables.MRUListPersistable toSerialize)
        {
            try
            {
                XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());

                using (StringWriter textWriter = new StringWriter())
                {
                    xmlSerializer.Serialize(textWriter, toSerialize);
                    return textWriter.ToString();
                }
            }
            catch (Exception e)
            {
                ////logger.Error(e);
            }

            return null;
        }

        #region Deserialize XML String to object
        /// <summary>
        /// Deserialize From Xml String.
        /// Source: http://stackoverflow.com/questions/2347642/deserialize-from-string-instead-textreader
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="objectData"></param>
        /// <returns></returns>
        public static T XmlDeserializeFromString<T>(string objectData)
        {
            return (T)XmlDeserializeFromString(objectData, typeof(T));
        }

        public static object XmlDeserializeFromString(string objectData, Type type)
        {
            object result = null;

            try
            {
                var serializer = new XmlSerializer(type);

                using (TextReader reader = new StringReader(objectData))
                {
                    result = serializer.Deserialize(reader);
                }
            }
            catch
            {
            }

            return result;
        }
        #endregion Deserialize XML String to object
        #endregion Xml String serialization
        #endregion methods
    }
}
